package org.lazy.generate.factory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.sql.ResultSetMetaData;
import java.util.HashSet;
import java.util.Set;

import org.lazy.generate.bean.GeneratorDataSource;
import org.lazy.generate.bean.GeneratorEntity;
import org.lazy.generate.bean.GeneratorTable;
import org.lazy.generate.common.XmlConstants;
import org.lazy.generate.util.SQLTypesUtil;

public class EntityConditionsFactory extends FileFactory{
	/**
	 * 创建EntityCondition
	 */
	public static void buildEntityCondition(GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		if(XmlConstants.IS_NEED_FALSE.equals(entity.getIsNeed())){
			System.out.println("ignore : "+table.getTableName()+" build EntityCondition");
			return;
		}
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityConditionClassName = createEntityConditionClassName(entityName, tableName);
		String targetPath = entity.getTargetPath();
		String entityPackage = entity.getTargetPackage();
		String entityFilePath = targetPath+"/"+entityPackage.replace(".", "/");
			PrintWriter pw = null;
			File file = createTargetClass(entityFilePath, entityConditionClassName);
			try {
				pw = new PrintWriter(file);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			//package
			pw.println("package "+entityPackage+";\n");
			//import
			Set<String> sets = needImport(metaData,dataSource);
			writeImportClass(pw, sets);
			pw.println("");
			//class
			pw.println("");
			pw.println("public class "+entityConditionClassName+"{\t");
			writeCondition(pw,dataSource, entity, table, metaData);
			pw.println("}");
			pw.flush();
			pw.close();
			System.out.println("success : "+entityConditionClassName+".java");
		
	}

	private static Set<String> needImport(ResultSetMetaData metaData,GeneratorDataSource dataSource) throws Exception{
		String dbType = dataSource.getDbType();
		Set<String> set = new HashSet<String>();
		set.add("java.util.ArrayList");
		set.add("java.util.List");
		set.add("org.lazy.generate.common.Condition");
		set.addAll(SQLTypesUtil.needImportClass(metaData,dbType));
		return set;
	}
	
	
	
	private static void writeCondition(PrintWriter pw,GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		String conditionEntity = "Condition";
		String conditions = "conditions";
		String dbType = dataSource.getDbType();
		pw.println(t1+"private List<Condition> conditions = new ArrayList<Condition>();");
		int colum = metaData.getColumnCount();
		for (int i = 1; i <= colum; i++) {
			int columnType = metaData.getColumnType(i);
			String columnName = metaData.getColumnName(i);
			String fieldName = createFieldName(columnName);
			String columnTypeName = metaData.getColumnTypeName(i);
			String fieldTypeName = SQLTypesUtil.getJavaType(columnType, columnTypeName,dbType);
			
			//IsNull
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"IsNull() {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" is null\"));");
			pw.println(t1+"}");
			//IsNotNull
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"IsNotNull() {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" is not null\"));");
			pw.println(t1+"}");
			//EqualTo
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"EqualTo("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" =\", value));");
			pw.println(t1+"}");
			//NotEqualTo
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"NotEqualTo("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" !=\", value));");
			pw.println(t1+"}");
			//Like
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"Like("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" like\",\"%\"+ value +\"%\"));");
			pw.println(t1+"}");
			//NotLike
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"NotLike("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" not like\",\"%\"+ value +\"%\"));");
			pw.println(t1+"}");
			//Between
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"Between("+fieldTypeName+" value1,"+fieldTypeName+" value2) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" between\", value1,value2));");
			pw.println(t1+"}");
			//NotBetween
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"NotBetween("+fieldTypeName+" value1,"+fieldTypeName+" value2) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" between\", value1,value2));");
			pw.println(t1+"}");
			//In
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"In(List<"+fieldTypeName+"> value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" in\", value));");
			pw.println(t1+"}");
			//NotIn
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"NotIn(List<"+fieldTypeName+"> value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" not in\", value));");
			pw.println(t1+"}");
			//MoreThan
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"MoreThan("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" > \", value ));");
			pw.println(t1+"}");
			//MoreThanOrEqual
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"MoreThanOrEqual("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" >= \", value ));");
			pw.println(t1+"}");
			//LessThan
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"LessThan("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" < \", value ));");
			pw.println(t1+"}");
			//LessThanOrEqual
			pw.println(t1+"public void and"+upperCaseFirstAlphabet(fieldName)+"LessThanOrEqual("+fieldTypeName+" value) {");
			pw.println(t2+conditions+".add(new "+conditionEntity+"(\""+columnName+" <= \", value ));");
			pw.println(t1+"}");
			
		}
		//分页相关参数
		writePage(pw);	
	}
	
	private static void writePage(PrintWriter pw){
		//分页相关
		pw.println(t1+"private Long pageNo;");
		pw.println(t1+"private Long pageSize;");
		pw.println(t1+"private Long startRow;");
		pw.println(t1+"private boolean isLimit;");
		pw.println(t1+"private String orderByClause;");
		pw.println(t1+"public void limit(Long pageNo,Long pageSize){");
		pw.println(t2+"this.pageNo = pageNo;");
		pw.println(t2+"this.pageSize = pageSize;");
		pw.println(t2+"this.startRow = (pageNo-1)*pageSize;");
		pw.println(t2+"this.isLimit = true;");
		pw.println(t1+"}");
		pw.println(t1+"public Long getPageNo() {");
		pw.println(t2+"return pageNo;");
		pw.println(t1+"}");
		pw.println(t1+"public Long getPageSize() {");
		pw.println(t2+"return pageSize;");
		pw.println(t1+"}");
		pw.println(t1+"public Long getStartRow() {");
		pw.println(t2+"return startRow;");
		pw.println(t1+"}");
		pw.println(t1+"public boolean isLimit() {");
		pw.println(t2+"return isLimit;");
		pw.println(t1+"}");
		pw.println(t1+"public void orderByClause(String orderByClause) {");
		pw.println(t2+"this.orderByClause = orderByClause;");
		pw.println(t1+"}");
		
	}
}
